package com.yj.rocketmq;


import com.yj.core.exception.ApiException;

/**
 * 消息枚举
 * <p>
 * mq消息目前下面几种方式：
 * <p>
 * 云->本地：
 * 1）云->指定医院指定服务
 * 2）云->所有医院指定服务
 * 3）云服务->云服务
 * <p>
 * 本地->云
 * 1）云->云服务
 * <p>
 * 本地->本地
 * 1）本地服务->本地服务
 * <p>
 * 问题：
 * 1）ConsumerGroup如何取？
 * 2）如何实现 云->指定医院指定服务 | 云->所有医院指定服务？
 * 3）希望topic跟医院没关系，如果topic有关系那将会创建特别多的topic
 * <p>
 * RocketMQ 订阅消息约束：
 * 1）同topic,多个同ConsumerGroup,消息将分算到多个ConsumerGroup上消费
 * 2）同topic,多个不同ConsumerGroup，每个ConsumerGroup都可以收到消息
 * 3）同topic,不同tag，在ConsumerGroup订阅不同tag，只接收订阅tag消息
 * <p>
 * 基于此，实现约定：
 * 1）消息订阅方订阅自己关注的topic和tag，必须通过topic|tag订阅，禁止tag=*
 * 2）ConsumerGroup取名用 服务名+[hosId],如：cloud-sync-100,通过这个来实现 云->所有医院指定服务 广播方式
 * 3）云->指定医院指定服务方式，tag必须是接收医院的id，接收医院通过tag=hosid订阅
 * 4）云->所有医院指定服务方式，tag不限制，根据实际情况定义，接收医院用topic和tag订阅
 * 5）本地->云上服务，tag根据实际情况定义
 * 6）其他的云服务->云服务或者 本地服务->本地服务，topic和tag根据自己情况自己定义，但是topic不能重复
 *
 * @author Xie
 * @date 19-3-25
 */
public interface MqConstants {
    String TAG_DIC = "DIC";
    String TAG_DIC_MAP = "DIC_MAP";
    String TAG_DEPT = "DEPT";
    String TAG_DRUG = "DRUG";
    String TAG_DOCT = "DOCT";
    String TAG_PAY = "PAY";
    String TAG_REFUND = "REFUND";

    String TAG_CLINIC_BOOOK = "BOOOK";
    String TAG_CLINIC_REG = "REG";
    String TAG_CLINIC_MASTER = "MASTER";
    String TAG_CLINIC_DRUG = "DRUG";
    String TAG_CLINIC_UNDRUG = "UNDRUG";

    String TAG_DIC_CATALOG = "DIC_CATALOG";
    String TAG_PARAM_BUSINESS = "PARAM_BUSINESS";
    String TAG_PARAMETER = "PARAMETER";
    String TAG_PARAM_VALUE = "PARAM_VALUE";
    String TAG_PATIENT = "PATIENT";
    String TAG_PATIENT_CARD = "PATIENT_CARD";
    String TAG_CONTACTS = "CONTACTS";
    String TAG_SEND_MSG = "TAG_SEND_MSG";
    String SECRET_PHONE = "SECRET_PHONE";
    String VOICE_NOTIFY = "VOICE_NOTIFY";
    String TAG_PAY_NOTIFY = "NOTIFY";
    String TAG_PAY_REFUND = "REFUND";
    String TAG_PAY_SYNC_PAY_RECORD = "PAYRECORD";
    String TAG_PAY_SYNC_REFUND_RECORD = "REFUNDRECORD";
    String TAG_BOOK_ORDER = "BOOK_ORDER";
    String TAG_BOOK_CANCEL = "BOOK_CANCEL";
    String TAG_REG_PAY_SUCC = "PAY_SUCCESS";
    String TAG_REG_STATE_FINISH = "FINISH";
    String TAG_REG_STATE_MISS = "MISS";
    String TAG_REG_STATE_QUIT = "QUIT";
    String TAG_REG_STATE_CANCEL = "CANCEL";
    String TAG_CARDBIND = "CARDBIND";

    String TAG_DOC_USER = "DOC_USER";

    String TAG_INCOME = "INCOME";

    String TAG_REC = "REC";
    String TAG_PACS = "PACS";
    String TAG_LIS = "LIS";
    String TAG_INHOS_MED = "INHOS_MED";
    String TAG_INHOS_ITEM = "INHOS_INHOS_ITEM";
    String TAG_APPOINT = "APPOINT";

    String TAG_HIS_BOOK = "BOOK";
    String TAG_HIS_BOOK_CANCEL = "BOOK_CANCEL";
    String TAG_STOCK = "STOCK";
    String TAG_PHA = "PHA";
    String TAG_REG_FINISHED = "REG_FINISHED";

    String TAG_CONVENIENT_SUCCESS = "TAG_CONVENIENT_SUCCESS";
    String TAG_CONVENIENT_FAIL = "TAG_CONVENIENT_FAIL";

    /**
     * 定义topic
     */
    enum MQ_TOPIC {
        /**
         * 本地上传mq消息->基础数据
         */
        LOCAL_2_CLOUD_BASICDATA("LOCAL_2_CLOUD_BASICDATA",
                TAG_DIC + "||" + TAG_DEPT + "||" + TAG_DRUG + "||" + TAG_DOCT,
                "上传基础数据(字典｜科室｜药品｜医生)"),
        /**
         * 本地上传mq消息->业务数据
         */
        LOCAL_2_CLOUD_PAY("LOCAL_2_CLOUD_PAY", TAG_PAY, "支付数据"),
        LOCAL_2_CLOUD_REFUND("LOCAL_2_CLOUD_REFUND", TAG_REFUND, "退款数据"),
        LOCAL_2_CLOUD_CLINIC("LOCAL_2_CLOUD_CLINIC",
                TAG_CLINIC_BOOOK + "||" + TAG_CLINIC_REG + "||" + TAG_CLINIC_MASTER + "||" + TAG_CLINIC_DRUG + "||" + TAG_CLINIC_UNDRUG,
                "问诊数据"),
        LOCAL_2_CLOUD_REG_PAY("LOCAL_2_CLOUD_REG_PAY", TAG_REG_PAY_SUCC, "问诊支付成功"),
        LOCAL_2_CLOUD_REG_STATE("LOCAL_2_CLOUD_REG_STATE", TAG_REG_STATE_FINISH + "||" + TAG_REG_STATE_QUIT + "||" + TAG_REG_STATE_MISS + "||" + TAG_REG_STATE_CANCEL, "完成|退诊|失约|取消"),

        LOCAL_2_CLOUD_CARDBIND("LOCAL_2_CLOUD_CARDBIND", TAG_CARDBIND, "绑卡数据"),
        LOCAL_2_CLOUD_CREATECARD("LOCAL_2_CLOUD_CREATECARD", TAG_CARDBIND, "建卡数据"),

        /**
         * 触发中间表上传mq消息(本地服务->本地服务)->业务数据
         */
        LOCAL_2_LOCAL_REC_DATA("LOCAL_2_LOCAL_REC_DATA", TAG_REC, "看诊数据(挂号表｜诊断表|医嘱表｜费用明细表)"),
        LOCAL_2_LOCAL_PACS_DATA("LOCAL_2_LOCAL_PACS_DATA", TAG_PACS, "检查结果数据"),
        LOCAL_2_LOCAL_LIS_DATA("LOCAL_2_LOCAL_LIS_DATA", TAG_LIS, "检验结果数据"),
        LOCAL_2_LOCAL_APPOINT_DATA("LOCAL_2_LOCAL_APPOINT_DATA", TAG_APPOINT, "预约数据(号源排班表|号源预约记录表)"),
        LOCAL_2_LOCAL_BOOK_SYNC("LOCAL_2_LOCAL_BOOK_SYNC", TAG_HIS_BOOK + "|| " + TAG_HIS_BOOK_CANCEL, "预约信息同步"),
        LOCAL_2_LOCAL_INHOS_MED_DATA("LOCAL_2_LOCAL_INHOS_MED_DATA", TAG_INHOS_MED, "住院药品费用明细表数据"),
        LOCAL_2_LOCAL_INHOS_ITEM_DATA("LOCAL_2_LOCAL_INHOS_ITEM_DATA", TAG_INHOS_ITEM, "住院非药品费用明细数据"),
        LOCAL_2_LOCAL_PHA_DATA("LOCAL_2_LOCAL_PHA_DATA", TAG_PHA, "药房相关数据"),

        /**
         * 下发mq消息－>基础数据
         */
        CLOUD_2_LOCAL_BROADCAST("CLOUD_2_LOCAL_BROADCAST",
                TAG_DIC_CATALOG + "||" + TAG_PARAM_BUSINESS + "||" + TAG_PARAMETER + "||" + TAG_PATIENT + "||" + TAG_CONTACTS,
                "下方广播数据（字典目录|参数目录|参数|已认证患者|家庭联系人）", true),
        CLOUD_2_LOCAL_GENERAL("CLOUD_2_LOCAL_GENERAL",
                TAG_DIC + "||" + TAG_DIC_MAP + "||" + TAG_PARAM_VALUE,
                "下发 字典值|医院参数值"),

        CLOUD_2_LOCAL_CREAREUSER("CLOUD_2_LOCAL_CREAREUSER", TAG_DIC_CATALOG + "||" + TAG_PARAM_BUSINESS + "||" + TAG_PARAMETER + "||" + TAG_PATIENT + "||" + TAG_CONTACTS,
                "下方广播数据（字典目录|参数目录|参数|已认证患者|家庭联系人）", true),
        CLOUD_2_LOCAL_UPDATEUSER("CLOUD_2_LOCAL_UPDATEUSER", TAG_DIC_CATALOG + "||" + TAG_PARAM_BUSINESS + "||" + TAG_PARAMETER + "||" + TAG_PATIENT + "||" + TAG_CONTACTS,
                "下方广播数据（字典目录|参数目录|参数|已认证患者|家庭联系人）", true),
        CLOUD_2_LOCAL_ADDACCOUNT("CLOUD_2_LOCAL_ADDACCOUNT", TAG_DIC_CATALOG + "||" + TAG_PARAM_BUSINESS + "||" + TAG_PARAMETER + "||" + TAG_PATIENT + "||" + TAG_CONTACTS,
                "下方广播数据（字典目录|参数目录|参数|已认证患者|家庭联系人）", true),
        CLOUD_2_LOCAL_UPDACCOUNT("CLOUD_2_LOCAL_UPDACCOUNT", TAG_DIC_CATALOG + "||" + TAG_PARAM_BUSINESS + "||" + TAG_PARAMETER + "||" + TAG_PATIENT + "||" + TAG_CONTACTS,
                "下方广播数据（字典目录|参数目录|参数|已认证患者|家庭联系人）", true),

        LOCAL_2_LOCAL_REGFINISHED("LOCAL_2_LOCAL_REGFINISHED", TAG_REG_FINISHED, "问诊完成"),

        CLOUD_2_LOCAL_MANAGE("CLOUD_2_LOCAL_MANAGE", TAG_INCOME, "云上到本地管理端结算消息"),


        /**
         * 云服务->云服务 消息
         */
        CLOUD_2_CLOUD_CREATE_DOC_USER("CLOUD_2_CLOUD_CREATE_DOC_USER",
                TAG_DOC_USER,
                "创建医生默认用户"),


        /**
         * 本地服务-本地服务 消息
         */
        LOCAL_BOOK_BOOK("LOCAL_BOOK_BOOK", TAG_BOOK_ORDER, ""),
        LOCAL_BOOK_CANCEL_BOOK("LOCAL_BOOK_CANCEL_BOOK", TAG_BOOK_CANCEL, ""),
        LOCAL_PAT_2_SYNC_CLINIC_RECORD("LOCAL_PAT_2_SYNC_CLINIC_RECORD", TAG_PATIENT_CARD, ""),

        /**
         * 本地服务->his 推送方便门诊审核数据
         */
        CONVENIENT("CONVENIENT", TAG_CONVENIENT_SUCCESS + "||" + TAG_CONVENIENT_FAIL, "方便门诊审核成功|方便门诊审核失败"),


        /**
         * 下发mq消息－>患者数据
         */
        SEND_SMS("SEND_MESSAGE", TAG_SEND_MSG, "发送消息(短信|推送|聊天信息)"),

        RECEIVE_REPORT("RECEIVE_REPORT", SECRET_PHONE + "||" + VOICE_NOTIFY, "接受话单消息(语音通知|号码隐私保护)"),

        PAY("PAY", TAG_PAY_NOTIFY + "||" + TAG_PAY_REFUND + "||" + TAG_PAY_SYNC_PAY_RECORD + "||" + TAG_PAY_SYNC_REFUND_RECORD, "支付业务", false),

        /**
         * 　药店服务－>药店服务　推送处方
         */
        CLOUD_PHARMACY_2_CLOUD_PHARMACY("CLOUD_PHARMACY_2_CLOUD_PHARMACY", TAG_PAY_NOTIFY, "药店支付成功后回调(向海典推处方)"),

        /**
         * 　药店服务－>本地服务　更新处方状态
         */
        CLOUD_PHARMACY_2_LOCAL("CLOUD_PHARMACY_2_LOCAL", TAG_PAY_NOTIFY, "药店支付成功后回调(更新处方状态)"),

        /**
         * 本地服务->云药店药品数据
         */
        LOCAL_2_CLOUD_PHARMACY_DATA("LOCAL_2_CLOUD_PHARMACY_DATA", TAG_STOCK + "||" + TAG_DRUG, "药店药品数据"),

        /**
         * 问诊系统通知医生端操作已经结束
         */
        CLOUD_2_CLOUD_CLINIC2DOC_OPERFINISHED("CLOUD_2_CLOUD_CLINIC_OPERFINISHED", TAG_REG_STATE_FINISH + "||" + TAG_REG_STATE_MISS + "||" + TAG_REG_STATE_QUIT + "||" + TAG_REG_STATE_CANCEL, "业务操作完成"),;

        /**
         * queue名称
         */
        private String topic;

        /**
         * 消息tag:多个tag用'||' 隔开，如:tag1||tag2||tag2
         * 禁止tags=* 或 tags=""
         */
        private String tags;

        /**
         * 数据种类
         */
        private String business;

        /**
         * 是否是广播消息
         * true：主要是云->本地情况广播情况，订阅tag时，按照用户配置的订阅
         * false：点->点情况，订阅tag时，按照tag+[hosid]订阅，比如：hosId=100, tags=NOTIFY||REFUND 实际订阅的 tags=NOTIFY&&100||REFUND&&100
         */
        private Boolean broadCast;


        MQ_TOPIC(String topic, String tags, String business) {
            this.topic = topic;
            this.tags = tags;
            this.business = business;
            this.broadCast = false;
        }

        MQ_TOPIC(String topic, String tags, String business, Boolean broadCast) {
            this.topic = topic;
            this.tags = tags;
            this.business = business;
            this.broadCast = broadCast;
        }

        public String getTopic() {
            return topic;
        }

        public String getTags() {
            return tags;
        }

        public String getBusiness() {
            return business;
        }

        public Boolean getBroadCast() {
            return broadCast;
        }

        public static MQ_TOPIC getMqTopic(String topic) {
            for (MQ_TOPIC t : values()) {
                if (t.getTopic().equalsIgnoreCase(topic)) {
                    return t;
                }
            }
            throw new ApiException(700002, "不支持的业务类型,topic=" + topic);
        }
    }

}
